package com.nbsaas.boot;

import javax.tools.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;

public class DynamicCodeExecutor1 {
    public static Object executeCode(String code) throws Exception {
        // 使用Java Compiler API编译代码并获取编译后的字节码数据
        byte[] byteCode = compileCode(code);
        
        // 加载并执行编译后的类
        MyClassLoader classLoader = new MyClassLoader();
        Class<?> loadedClass = classLoader.loadClass("DynamicCode", byteCode);
        Method method = loadedClass.getMethod("execute");
        return method.invoke(null);
    }

    // 使用Java Compiler API编译代码并返回编译后的字节码数据
    private static byte[] compileCode(String code) throws IOException {
        // 获取编译器实例
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        if (compiler == null) {
            throw new RuntimeException("Java编译器未找到，请确保JDK安装正确");
        }

        // 创建文件管理器
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        // 创建一个内存中的输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        // 创建编译任务
        Writer out=new StringWriter();
        JavaCompiler.CompilationTask task = compiler.getTask(out, fileManager, null, null, null, Arrays.asList(new JavaSourceFromString("DynamicCode", code)));

        // 执行编译任务
        boolean success = task.call();
        fileManager.close();

        if (!success) {
            throw new RuntimeException("代码编译失败");
        }

        // 从输出流中获取编译后的字节码数据
        return outputStream.toByteArray();
    }

    // 自定义Java源文件对象
    static class JavaSourceFromString extends SimpleJavaFileObject {
        final String code;

        JavaSourceFromString(String className, String code) {
            super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
            this.code = code;
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return this.code;
        }
    }

    // 自定义ClassLoader用于加载动态编译后的类
    static class MyClassLoader extends ClassLoader {
        public Class<?> loadClass(String name, byte[] byteCode) {
            return defineClass(name, byteCode, 0, byteCode.length);
        }
    }

    public static void main(String[] args) {
        String code = "public class DynamicCode { public static void execute() { System.out.println(\"Dynamic code executed\"); } }";
        try {
            executeCode(code);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
